/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022.  All rights reserved.2023.
 */

package service

//独立的订单服务，不依赖其他服务

import (
	"fmt"
	"prim-server/common"
	"prim-server/dao"
	"prim-server/logger"
	"prim-server/model"
	"prim-server/util"
	"prim-server/util/toolcbc"
	"sync"
	"time"

	bssModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/bss/v2/model"
	"github.com/pkg/errors"
)

const (
	deFaultCurrency = "CNY"

	//云上订单
	platformTypeOfCloud = "1"
	//自有订单
	platformTypeOfSelf = "2"

	//订单状态--和云上订单保持一致--不区分按需和包周期
	//待审核
	orderStatusOfToBeReviewed = int32(1)
	//处理中
	orderStatusOfProcessing = int32(3)
	//已取消
	orderStatusOfCancelled = int32(4)
	//已完成
	orderStatusOfCompleted = int32(5)
	//待支付
	orderStatusOfToBePaid = int32(6)
	//待确认
	orderStatusOfToBeConfirmed = int32(9)

	//orderby
	orderByReverse = "-createTime"
	orderByUp      = "+createTime"

	timeFormatLayout = "2006-01-02T15:04:05Z"
)

const (
	//云上按需资源有效状态
	//1.正常(已开通) 2. 宽限期
	resourceStatusOfNormal      = int32(1)
	resourceStatusOfGracePeriod = int32(2)
	resourceStatusOfFrozen      = int32(3)
	resourceStatusOfChanging    = int32(4)
	resourceStatusOfClosing     = int32(5)
	resourceStatusOfClosed      = int32(6)

	//按需订单类型 1--新购 2--变更
	onDemandOrderTypeOfPurchase = int32(1)
	onDemandOrderTypeOfChange   = int32(3)

	defaultLimit  = int32(50)
	defaultOffset = int32(0)
)

var (
	lock sync.Mutex

	orderByDefault     = orderByUp
	defaultOrderStatus = orderStatusOfCompleted
)

var usedOrderStatus map[int32]bool

func init() {
	usedOrderStatus = make(map[int32]bool)
	usedOrderStatus[orderStatusOfToBeReviewed] = true
	usedOrderStatus[orderStatusOfProcessing] = true
	usedOrderStatus[orderStatusOfCancelled] = true
	usedOrderStatus[orderStatusOfCompleted] = true
	usedOrderStatus[orderStatusOfToBePaid] = true
	usedOrderStatus[orderStatusOfToBeConfirmed] = true
}

// 判断是否为有效的订单状态
func ValidateOrderStatus(orderStatus int32) bool {
	if _, ok := usedOrderStatus[orderStatus]; ok {
		return true
	}
	return false
}

// 获取平台类型
func GetPlatformTypeOfCloud() string {
	return platformTypeOfCloud
}
func GetPlatformTypeOfSelf() string {
	return platformTypeOfSelf
}

// 是否属于云上订单
func IsCloudPlatform(platformType string) bool {
	return platformType == platformTypeOfCloud
}

// 是否属于平台自有订单
func IsSelfPlatform(platformType string) bool {
	return platformType == platformTypeOfSelf
}

// 是否处于待支付订单
func IsOrderStatusOfToBePaid(orderStatus int32) bool {
	return orderStatus == orderStatusOfToBePaid
}
func CreateDefaultOnePayOrder(userId, platformType string, currency *string, orderStatus *int32) *model.OnePayOrder {
	order := &model.OnePayOrder{
		OrderId:      util.GetUUID32(),
		UserId:       userId,
		CouponId:     "",
		PlatformType: platformType,
		Currency:     deFaultCurrency,
	}
	if orderStatus != nil {
		order.OrderStatus = *orderStatus
	}
	if currency != nil {
		order.Currency = *currency
	}
	return order
}

// 根据包周期资源消费记录创建包周期订单
func CreateOnePayOrderWithCloudResourceFeeRecord(userId string, currency *string,
	cloudResourceRecord *bssModel.ResFeeRecordV2) (orderId string, retOrder *model.OnePayOrder, err error) {
	if cloudResourceRecord == nil {
		return "", nil, nil
	}
	orderStatus := orderStatusOfCompleted
	order := CreateDefaultOnePayOrder(userId, platformTypeOfCloud, currency, &orderStatus)
	if cloudResourceRecord.TradeId != nil {
		order.CloudOrderId = *cloudResourceRecord.TradeId
	}
	if cloudResourceRecord.CustomerId != nil {
		order.CloudUserId = *cloudResourceRecord.CustomerId
	}
	if cloudResourceRecord.TradeTime != nil {
		cloudOrderTradeTime, err := util.GetTimeFromUTCStr(*cloudResourceRecord.TradeTime)
		if err != nil {
			logger.Error("create one pay order error: %v, userId: %s", err.Error(), userId)
		}
		order.CreatedTime = cloudOrderTradeTime
		order.PaymentTime = cloudOrderTradeTime
		order.OrderExpiredTime = order.CreatedTime.Add(6*24*time.Hour + 23*time.Hour)
		order.ResourceExpiredTime = util.GetDefaultTime()
	}
	if cloudResourceRecord.OfficialAmount != nil {
		order.OriginAmount = *cloudResourceRecord.OfficialAmount
	}
	if cloudResourceRecord.Amount != nil {
		order.PaymentAmount = *cloudResourceRecord.Amount
	}
	if cloudResourceRecord.CloudServiceTypeName != nil {
		order.ServiceTypeName = *cloudResourceRecord.CloudServiceTypeName
	}
	if cloudResourceRecord.CloudServiceType != nil {
		order.ServiceTypeCode = *cloudResourceRecord.CloudServiceType
	}
	if cloudResourceRecord.ExpireTime != nil {
		cloudOrderExpireTime, err := util.GetTimeFromUTCStr(*cloudResourceRecord.TradeTime)
		if err != nil {
			logger.Error("create one pay order error: %v, userId: %s", err.Error(), userId)
		}
		order.ResourceExpiredTime = cloudOrderExpireTime
	}
	if cloudResourceRecord.ProductSpecDesc != nil {
		order.ProductionSpecDesc = *cloudResourceRecord.ProductSpecDesc
	}
	return order.OrderId, order, nil
}

// 根据包周期订单创建包周期订单
func CreateOnePayOrderWithCloudBill(userId string, currency *string,
	cloudBill *bssModel.MonthlyBillRecord) (orderId string, retOrder *model.OnePayOrder, err error) {
	if cloudBill == nil {
		return "", nil, nil
	}
	orderStatus := orderStatusOfCompleted
	order := CreateDefaultOnePayOrder(userId, platformTypeOfCloud, currency, &orderStatus)
	if cloudBill.TradeId != nil {
		order.CloudOrderId = *cloudBill.TradeId
	}
	if cloudBill.CustomerId != nil {
		order.CloudUserId = *cloudBill.CustomerId
	}
	if cloudBill.TradeTime != nil {
		cloudOrderTradeTime, err := util.GetTimeFromUTCStr(*cloudBill.TradeTime)
		if err != nil {
			logger.Error("create one pay order error: %v, userId: %s", err.Error(), userId)
		}
		order.CreatedTime = cloudOrderTradeTime
		order.PaymentTime = cloudOrderTradeTime
		order.OrderExpiredTime = order.CreatedTime.Add(6*24*time.Hour + 23*time.Hour)
		order.ResourceExpiredTime = util.GetDefaultTime()
	}
	if cloudBill.OfficialAmount != nil {
		order.OriginAmount = *cloudBill.OfficialAmount
	}
	if cloudBill.ConsumeAmount != nil {
		order.PaymentAmount = *cloudBill.ConsumeAmount
	}
	if cloudBill.ServiceTypeName != nil {
		order.ServiceTypeName = *cloudBill.ServiceTypeName
	}
	if cloudBill.ServiceTypeCode != nil {
		order.ServiceTypeCode = *cloudBill.ServiceTypeCode
	}
	//拉取云上订单详情
	detail, err := PullCloudOnePayOrderDetail(order.CloudOrderId, nil, nil, nil)
	if err != nil {
		logger.Error("create one pay order error: %v, userId: %s", err.Error(), userId)
	}
	productSpecDesc, resourceExpiredTime := BuildDescAndExpireTimeFromOnePayOrderDetail(detail)
	order.ProductionSpecDesc = productSpecDesc
	order.ResourceExpiredTime = resourceExpiredTime
	return order.OrderId, order, nil
}
func CreateOnePayOrderWithCloudOrder(userId, platformType, couponId string,
	cloudOrder bssModel.CustomerOrderV2) *model.OnePayOrder {
	order := CreateDefaultOnePayOrder(userId, platformType, cloudOrder.Currency, cloudOrder.Status)
	cloudOrderCreateTime, err := util.GetTimeFromUTCStr(*cloudOrder.CreateTime)
	if err != nil {
		logger.Error("create one pay order error: %v, userId: %s", err.Error(), userId)
	}
	cloudOrderPaymentTime := cloudOrderCreateTime
	if cloudOrder.PaymentTime != nil {
		cloudOrderPaymentTime, err = util.GetTimeFromUTCStr(*cloudOrder.PaymentTime)
		if err != nil {
			logger.Error("create one pay order error: %v, userId: %s", err.Error(), userId)
		}
	}
	order.CreatedTime = cloudOrderCreateTime
	order.PaymentTime = cloudOrderPaymentTime
	order.OrderExpiredTime = order.CreatedTime.Add(6*24*time.Hour + 23*time.Hour)
	order.ResourceExpiredTime = util.GetDefaultTime()
	if cloudOrder.CustomerId != nil {
		order.CloudUserId = *cloudOrder.CustomerId
	}
	if cloudOrder.OrderId != nil {
		order.CloudOrderId = *cloudOrder.OrderId
	}
	if cloudOrder.ServiceTypeName != nil {
		order.ServiceTypeName = *cloudOrder.ServiceTypeName
	}
	if cloudOrder.ServiceTypeCode != nil {
		order.ServiceTypeCode = *cloudOrder.ServiceTypeCode
	}
	if cloudOrder.OfficialAmount != nil {
		order.OriginAmount = *cloudOrder.OfficialAmount
	}
	if cloudOrder.AmountAfterDiscount != nil {
		order.PaymentAmount = *cloudOrder.AmountAfterDiscount
	}
	if cloudOrder.OrderType != nil {
		order.OrderType = *cloudOrder.OrderType
	}
	//拉取云上订单详情
	detail, err := PullCloudOnePayOrderDetail(*cloudOrder.OrderId, nil, nil, nil)
	if err != nil {
		logger.Error("create one pay order error: %v, userId: %s", err.Error(), userId)
	}
	productSpecDesc, resourceExpiredTime := BuildDescAndExpireTimeFromOnePayOrderDetail(detail)
	order.ProductionSpecDesc = productSpecDesc
	order.ResourceExpiredTime = resourceExpiredTime
	return order
}
func CreateOnePayOrder(platformType, cloudOrderId, userId, cloudUserId, currency, couponId,
	serviceTypeName, serviceTypeCode, productSpecDesc string,
	createTime, paymentTime time.Time, originAmount, paymentAmount float64,
	orderType, orderStatus int32, isUTC bool) *model.OnePayOrder {
	order := &model.OnePayOrder{
		OrderId:            util.GetUUID32(),
		PlatformType:       platformType,
		OrderType:          orderType,
		CloudOrderId:       cloudOrderId,
		UserId:             userId,
		CloudUserId:        cloudUserId,
		OrderStatus:        orderStatus,
		CreatedTime:        createTime,
		PaymentTime:        paymentTime,
		Currency:           currency,
		OriginAmount:       originAmount,
		PaymentAmount:      paymentAmount,
		CouponId:           couponId,
		ServiceTypeName:    serviceTypeName,
		ServiceTypeCode:    serviceTypeCode,
		ProductionSpecDesc: productSpecDesc,
	}
	if !isUTC {
		order.CreatedTime = util.GetUTC(createTime)
		order.PaymentTime = util.GetUTC(paymentTime)
	}
	return order
}
func CreateAndSaveOnePayOrder(platformType, cloudOrderId, userId, cloudUserId,
	currency, couponId, serviceTypeName, serviceTypeCode, productSpecDesc string,
	creatTime, paymentTime time.Time,
	originAmount, paymentAmount float64, orderType, orderStatus int32, isUTC bool) error {
	order := CreateOnePayOrder(platformType, cloudOrderId, userId, cloudUserId,
		currency, couponId, serviceTypeName, serviceTypeCode, productSpecDesc,
		creatTime, paymentTime, originAmount, paymentAmount,
		orderType, orderStatus, isUTC)
	return SaveOnePayOrder([]*model.OnePayOrder{order})
}

func SaveOnePayOrder(orders []*model.OnePayOrder) error {
	err := dao.GetOnePayOrderDao().SaveOnePayOrderInfo(orders)
	if err != nil {
		logger.Error("save one pay order error: %v", err.Error())
		return errors.New("增加订单失败")
	}
	return nil
}
func SaveOnDemandOrder(orders []*model.OnDemandOrder) error {
	err := dao.GetOnDemandOrderao().SaveOnDemandOrderInfo(orders)
	if err != nil {
		logger.Error("save on demand order error: %v", err.Error())
		return errors.New("增加订单失败")
	}
	return nil
}

// 创建云上包周期订单
func CreateAndSaveCloudOnePayOrder(userId, couponId string,
	cloudOrders *bssModel.ListCustomerOrdersResponse) (*time.Time, error) {
	if cloudOrders == nil {
		return nil, nil
	}
	if *cloudOrders.TotalCount == 0 {
		return nil, nil
	}
	//记录最新更新时间
	updateTime := util.GetDefaultTime()
	//以年份为跨度
	createdTime := util.GetUTC(time.Now())
	orders := [3][]*model.OnePayOrder{}
	//按年份划分orders,createdTime-1,createdTime,createdTime+1年，总共3年
	createdYearNow := createdTime.Year()
	createdYearBefore := createdYearNow - 1
	platformType := platformTypeOfCloud
	for _, cloudOrder := range *cloudOrders.OrderInfos {
		order := CreateOnePayOrderWithCloudOrder(userId, platformType, couponId, cloudOrder)
		orderTime := order.CreatedTime.Year() - createdYearBefore
		orders[orderTime] = append(orders[orderTime], order)
		if order.CreatedTime.After(updateTime) {
			updateTime = order.CreatedTime
		}
	}
	//批量插入order
	errStr := ""
	for _, orderData := range orders {
		err := dao.GetOnePayOrderDao().SaveOnePayOrderInfo(orderData)
		if err != nil {
			logger.Error("save one pay order error: %v, userId: %s", err.Error(), userId)
			errStr = "更新订单失败"
		}
	}
	if len(errStr) != 0 {
		return nil, errors.New(errStr)
	}
	return &updateTime, nil
}

// 拉取云上包周期订单详情
func PullCloudOnePayOrderDetail(cloudOrderId string, limit, offset *int32, indirectPartnerId *string) (*bssModel.ShowCustomerOrderDetailsResponse, error) {
	response, err := toolcbc.GetCloudOnePayOrderDetail(cloudOrderId, limit, offset, indirectPartnerId)
	if err != nil {
		logger.Error("get cloud one pay order error: %v, cloudOrderId: %s", err.Error(), cloudOrderId)
		return nil, errors.New("获取订单详情失败")
	}
	return response, nil
}

// 从云上包周期订单详情组成产品规格描述
func BuildDescAndExpireTimeFromOnePayOrderDetail(response *bssModel.ShowCustomerOrderDetailsResponse) (string, time.Time) {
	productSpecDesc := ""
	resourceExpiredTime := util.GetDefaultTime()
	if response == nil {
		return productSpecDesc, resourceExpiredTime
	}
	if *response.TotalCount == 0 {
		return productSpecDesc, resourceExpiredTime
	}
	for _, detail := range *response.OrderLineItems {
		productSpecDesc += fmt.Sprintf("%s\n", *detail.ProductSpecDesc)
	}
	for _, info := range *response.OrderLineItems {
		if info.ExpireTime != nil {
			expiredTime, err := util.GetTimeFromUTCStr(*info.ExpireTime)
			if err != nil {
				logger.Error(err.Error())
				continue
			}
			resourceExpiredTime = expiredTime
		}
	}
	return productSpecDesc, resourceExpiredTime
}
func PullCloudOnePayOrderDetailAll(cloudOrderIds []string, limits, offsets []*int32, indirectPartnerIds []*string) ([]*bssModel.ShowCustomerOrderDetailsResponse, error) {
	num := len(cloudOrderIds)
	if num == 0 {
		return nil, nil
	}
	useLimit := false
	useOffset := false
	useIndirectPartnerId := false
	if num == len(limits) {
		useLimit = true
	}
	if num == len(offsets) {
		useOffset = true
	}
	if num == len(indirectPartnerIds) {
		useIndirectPartnerId = true
	}
	resultData := []*bssModel.ShowCustomerOrderDetailsResponse{}
	for index, _ := range cloudOrderIds {
		cloudOrderId := cloudOrderIds[index]
		var limit *int32 = nil
		var offset *int32 = nil
		var indirectPartnerId *string = nil
		if useLimit {
			limit = limits[index]
		}
		if useOffset {
			offset = offsets[index]
		}
		if useIndirectPartnerId {
			indirectPartnerId = indirectPartnerIds[index]
		}
		response, err := toolcbc.GetCloudOnePayOrderDetail(cloudOrderId, limit, offset, indirectPartnerId)
		if err != nil {
			logger.Error("get cloud one pay order error: %v, cloudOrderId: %s", err.Error(), fmt.Sprint(cloudOrderId))
			return nil, errors.New("获取订单详情失败")
		}
		resultData = append(resultData, response)
	}
	return resultData, nil
}

// 拉取云上包周期订单列表
func PullCloudOnePayOrder(cloudOrderId, cloudUserId, createTimeBegin, createTimeEnd,
	serviceTypeCode, orderType, orderBy, paymentTimeBegin, paymentTimeEnd, indirectPartnerId *string,
	orderStatus, limit, offset *int32) (*bssModel.ListCustomerOrdersResponse, error) {
	response, err := toolcbc.GetCloudOrders(
		cloudOrderId, cloudUserId, createTimeBegin, createTimeEnd,
		serviceTypeCode, orderType, orderBy, paymentTimeBegin, paymentTimeEnd, indirectPartnerId,
		orderStatus, limit, offset)
	if err != nil {
		logger.Error("get cloud one pay error: %v, cloudOrderId: %s, cloudUserId: %s", err.Error(), cloudOrderId, cloudUserId)
		return nil, errors.New("获取订单失败")
	}
	return response, nil
}
func PullAndSaveCloudOnePayOrderAll(userId, couponId string, cloudOrderId, cloudUserId, createTimeBegin, createTimeEnd,
	serviceTypeCode, orderType, orderBy, paymentTimeBegin, paymentTimeEnd, indirectPartnerId *string,
	orderStatus, limit, offset *int32) (*time.Time, error) {
	var updateTime *time.Time = nil
	for {
		//拉取云上包周期订单
		response, err := PullCloudOnePayOrder(
			cloudOrderId, cloudUserId, createTimeBegin, createTimeEnd,
			serviceTypeCode, orderType, orderBy, paymentTimeBegin, paymentTimeEnd, indirectPartnerId,
			orderStatus, limit, offset)
		if err != nil {
			logger.Error(err.Error())
			return nil, err
		}
		if *response.TotalCount == 0 {
			break
		}
		//创建包周期订单
		lastTime, err := CreateAndSaveCloudOnePayOrder(userId, couponId, response)
		if err != nil {
			logger.Error(err.Error())
			return nil, err
		}
		if updateTime == nil {
			updateTime = lastTime
		} else {
			if lastTime != nil {
				if (*lastTime).After(*updateTime) {
					*updateTime = *lastTime
				}
			}
		}
		if (*limit + *offset) > *response.TotalCount {
			break
		}
		*offset = (*offset + *limit)
	}
	return updateTime, nil
}
func PullAndSaveCloudOnePayOrderLastestOne(userId, couponId, cloudUserId string) error {
	limit := defaultLimit
	offset := defaultOffset
	//获取更新时间(UTC)
	orderRecord, err := GetOrderUpdateRecordOneWithUserId(userId)
	if err != nil {
		return err
	}
	if orderRecord == nil {
		logger.Warn("Can't find the one pay order update time of record.")
		return nil
	}
	createTimeBeg := util.GetTimeString(orderRecord.OnePayOrderUpdateTime)
	updateTime, err := PullAndSaveCloudOnePayOrderAll(userId, couponId, nil, &cloudUserId,
		&createTimeBeg, nil, nil, nil, &orderByDefault, nil, nil, nil,
		nil, &limit, &offset)
	if err != nil {
		return err
	}
	//更新拉取时间(UTC)
	var updateTimeSec *int64
	if updateTime != nil {
		lastTime := (*updateTime).Add(1 * time.Second)
		timeSec := util.GetMilliSec(lastTime)
		updateTimeSec = &timeSec
	}
	err = UpdateOrderRecord(userId, updateTimeSec, nil)
	if err != nil {
		return err
	}
	//开通订单，资源加一，退订资源减一，按需转包年包月资源加一
	return nil
}

// 对所有用户拉取包周期订单
func PullAndSaveCloudOrderLastestAll(userId, couponId, cloudUserId []string) error {
	if len(userId) == 0 || len(cloudUserId) == 0 {
		return nil
	}
	useCouponId := false
	if len(couponId) == len(userId) && len(userId) > 0 {
		useCouponId = true
	}
	for index, _ := range userId {
		nowUser := userId[index]
		nowCouponId := ""
		if useCouponId {
			nowCouponId = couponId[index]
		}
		nowCloudUser := cloudUserId[index]
		err := PullAndSaveCloudOnePayOrderLastestOne(nowUser, nowCouponId, nowCloudUser)
		if err != nil {
			logger.Error(err.Error())
			return err
		}
	}
	return nil
}

// 查询包周期订单
func BuildQueryParameterForGetOnePayOrder(userId, cloudUserId, orderId, platformType,
	cloudOrderId []string, orderType, orderStatus []int32,
	createdTimeBegin, createdTimeEnd, paymentTimeBegin, paymentTimeEnd *int64,
	currency *string,
	page, pageSize *int, timeReverseOrder *bool) *common.QueryOnePayOrderDetail {
	queryParameter := &common.QueryOnePayOrderDetail{
		UserId:           userId,
		CloudUserId:      cloudUserId,
		OrderId:          orderId,
		PlatformType:     platformType,
		OrderType:        orderType,
		CloudOrderId:     cloudOrderId,
		OrderStatus:      orderStatus,
		CreatedTimeBegin: createdTimeBegin,
		CreatedTimeEnd:   createdTimeEnd,
		PaymentTimeBegin: paymentTimeBegin,
		PaymentTimeEnd:   paymentTimeEnd,
		Currency:         currency,
		Page:             page,
		PageSize:         pageSize,
		TimeReverseOrder: timeReverseOrder,
	}
	return queryParameter
}
func GetOnePayOrderAllWithParamenter(queryParameter *common.QueryOnePayOrderDetail) ([]*model.OnePayOrder, int, error) {
	onePayOrder, totalCount, err := dao.GetOnePayOrderDao().GetOnePayOrderInfo(queryParameter)
	if err != nil {
		logger.Error(err.Error())
		return nil, 0, errors.New("查询包周期订单失败")
	}
	return onePayOrder, totalCount, nil
}
func GetOnePayOrderAll(userId, cloudUserId, orderId, platformType,
	cloudOrderId []string, orderType, orderStatus []int32,
	createdTimeBegin, createdTimeEnd, paymentTimeBegin, paymentTimeEnd *int64,
	currency *string, page, pageSize *int, timeReverseOrder *bool) ([]*model.OnePayOrder, int, error) {
	return GetOnePayOrderAllWithParamenter(BuildQueryParameterForGetOnePayOrder(userId, cloudUserId,
		orderId, platformType, cloudOrderId, orderType, orderStatus,
		createdTimeBegin, createdTimeEnd, paymentTimeBegin, paymentTimeEnd,
		currency, page, pageSize, timeReverseOrder))
}
func GetOnePayOrderWithOrderId(orderId string) (*model.OnePayOrder, error) {
	queryParameter := &common.QueryOnePayOrderDetail{
		OrderId: []string{orderId},
	}
	onePayOrder, totalCount, err := GetOnePayOrderAllWithParamenter(queryParameter)
	if err != nil {
		logger.Error("get one pay order error: %v, orderId: %s", err.Error(), orderId)
		return nil, err
	}
	if totalCount == 0 {
		return nil, nil
	}
	return onePayOrder[0], nil
}
func GetOnePayOrderWithCloudOrderId(cloudOrderId string) (*model.OnePayOrder, error) {
	queryParameter := &common.QueryOnePayOrderDetail{
		CloudOrderId: []string{cloudOrderId},
	}
	onePayOrder, totalCount, err := GetOnePayOrderAllWithParamenter(queryParameter)
	if err != nil {
		logger.Error("get one pay order error: %v, cloudOrderId: %s", err.Error(), cloudOrderId)
		return nil, err
	}
	if totalCount == 0 {
		return nil, nil
	}
	return onePayOrder[0], nil
}

// 根据云上按需账单创建按需资源订单
func CreateOnDemandOrderWithCloudBill(userId string, cloudResourceId,
	cloudResourceName, productSpecDesc, currency *string,
	cloudBill *bssModel.MonthlyBillRecord) (orderId string, retOrder *model.OnDemandOrder, err error) {
	if cloudBill == nil {
		return "", nil, nil
	}
	order := &model.OnDemandOrder{
		OrderId:              util.GetUUID32(),
		UserId:               userId,
		CouponId:             "",
		PlatformType:         platformTypeOfCloud,
		OrderType:            onDemandOrderTypeOfPurchase,
		OrderStatus:          orderStatusOfCompleted,
		AvailabilityZoneCode: "",
	}
	if cloudResourceId != nil {
		order.ResourceId = *cloudResourceId
	}
	if currency != nil {
		order.Currency = *currency
	}
	if cloudBill.ConsumeTime != nil {
		beginTime := (*cloudBill.ConsumeTime)[:len(timeFormatLayout)]
		cloudResourceCreateTime, err := util.GetTimeFromUTCStr(beginTime)
		if err != nil {
			logger.Error("get resource time error: %v, userId: %s, billEffectiveTime: %s", err.Error(), userId, beginTime)
		}
		order.CreatedTime = cloudResourceCreateTime
	}
	if cloudBill.CustomerId != nil {
		order.CloudUserId = *cloudBill.CustomerId
	}
	if cloudBill.RegionCode != nil {
		order.RegionCode = *cloudBill.RegionCode
	}
	if cloudResourceName != nil {
		order.CloudResourceName = *cloudResourceName
	}
	if cloudBill.ServiceTypeCode != nil {
		order.ServiceTypeCode = *cloudBill.ServiceTypeCode
	}
	if cloudBill.ServiceTypeName != nil {
		order.ServiceTypeName = *cloudBill.ServiceTypeName
	}
	if productSpecDesc != nil {
		order.ProductSpecDesc = *productSpecDesc
	}
	return order.OrderId, order, nil
}

// 根据云上资源消费记录创建按需订单
func CreateOnDemandOrderWithCloudResourceRecord(userId string, currency *string,
	cloudResourceFeeRecord *bssModel.ResFeeRecordV2) (orderId string, retOrder *model.OnDemandOrder, err error) {
	if cloudResourceFeeRecord == nil {
		return "", nil, nil
	}
	order := &model.OnDemandOrder{
		OrderId:              util.GetUUID32(),
		UserId:               userId,
		CouponId:             "",
		PlatformType:         platformTypeOfCloud,
		OrderType:            onDemandOrderTypeOfPurchase,
		OrderStatus:          orderStatusOfCompleted,
		AvailabilityZoneCode: "",
	}
	if cloudResourceFeeRecord.ResourceId != nil {
		order.ResourceId = *cloudResourceFeeRecord.ResourceId
	}
	if currency != nil {
		order.Currency = *currency
	}
	if cloudResourceFeeRecord.EffectiveTime != nil {
		cloudResourceCreateTime, err := util.GetTimeFromUTCStr(*cloudResourceFeeRecord.EffectiveTime)
		if err != nil {
			logger.Error("get resource time error: %v, userId: %s, billEffectiveTime: %s", err.Error(), userId, *cloudResourceFeeRecord.EffectiveTime)
		}
		order.CreatedTime = cloudResourceCreateTime
	}
	if cloudResourceFeeRecord.CustomerId != nil {
		order.CloudUserId = *cloudResourceFeeRecord.CustomerId
	}
	if cloudResourceFeeRecord.Region != nil {
		order.RegionCode = *cloudResourceFeeRecord.Region
	}
	if cloudResourceFeeRecord != nil {
		order.CloudResourceName = *cloudResourceFeeRecord.ResourceTypeName
	}
	if cloudResourceFeeRecord.CloudServiceType != nil {
		order.ServiceTypeCode = *cloudResourceFeeRecord.CloudServiceType
	}
	if cloudResourceFeeRecord.CloudServiceTypeName != nil {
		order.ServiceTypeName = *cloudResourceFeeRecord.CloudServiceTypeName
	}
	if cloudResourceFeeRecord.ProductSpecDesc != nil {
		order.ProductSpecDesc = *cloudResourceFeeRecord.ProductSpecDesc
	}
	return order.OrderId, order, nil
}

// 创建按需资源订单
func CreateOnDemandOrderWithCloudResource(userId, platformType, couponId string,
	orderType, orderStatus int32, cloudResource bssModel.CustomerOnDemandResource) *model.OnDemandOrder {
	order := &model.OnDemandOrder{
		OrderId:      util.GetUUID32(),
		UserId:       userId,
		CouponId:     couponId,
		PlatformType: platformType,
		OrderType:    orderType,
		OrderStatus:  orderStatus,
		Currency:     deFaultCurrency,
	}
	if cloudResource.EffectiveTime != nil {
		cloudResourceCreateTime, err := util.GetTimeFromUTCStr(*cloudResource.EffectiveTime)
		if err != nil {
			logger.Error("get resource time error: %v, userId: %s, billEffectiveTime: %s", err.Error(), userId, *cloudResource.EffectiveTime)
		}
		order.CreatedTime = cloudResourceCreateTime
	}
	if cloudResource.CustomerId != nil {
		order.CloudUserId = *cloudResource.CustomerId
	}
	if cloudResource.ResourceId != nil {
		order.ResourceId = *cloudResource.ResourceId
	}
	if cloudResource.ResourceName != nil {
		order.CloudResourceName = *cloudResource.ResourceName
	}
	if cloudResource.RegionCode != nil {
		order.RegionCode = *cloudResource.RegionCode
	}
	if cloudResource.AvailabilityZoneCode != nil {
		order.AvailabilityZoneCode = *cloudResource.AvailabilityZoneCode
	}
	if cloudResource.ServiceTypeCode != nil {
		order.ServiceTypeCode = *cloudResource.ServiceTypeCode
	}
	if cloudResource.ServiceTypeName != nil {
		order.ServiceTypeName = *cloudResource.ServiceTypeName
	}
	if cloudResource.ProductSpecDesc != nil {
		order.ProductSpecDesc = *cloudResource.ProductSpecDesc
	}
	return order
}
func CreateOnDemandOrder(userId, platformType, couponId,
	cloudUserId, cloudResourceId, cloudResourceName, regionCode,
	availabilityZoneCode, serviceTypeCode, serviceTypeName, productSpecDesc string,
	createTime time.Time, orderType, orderStatus int32, isUTC bool) *model.OnDemandOrder {
	order := &model.OnDemandOrder{
		OrderId:              util.GetUUID32(),
		UserId:               userId,
		PlatformType:         platformType,
		CloudUserId:          cloudUserId,
		ResourceId:           cloudResourceId,
		CloudResourceName:    cloudResourceName,
		CouponId:             couponId,
		OrderType:            orderType,
		CreatedTime:          createTime,
		OrderStatus:          orderStatus,
		RegionCode:           regionCode,
		AvailabilityZoneCode: availabilityZoneCode,
		ServiceTypeCode:      serviceTypeCode,
		ServiceTypeName:      serviceTypeName,
		ProductSpecDesc:      productSpecDesc,
	}
	if IsSelfPlatform(platformType) {
		order.ResourceId = util.GetUUID32()
	}
	if !isUTC {
		order.CreatedTime = util.GetUTC(createTime)
	}
	return order
}

func CreateAndSaveOnDemandOrder(userId, platformType, couponId,
	cloudUserId, cloudResourceId, cloudResourceName, regionCode,
	availabilityZoneCode, serviceTypeCode, serviceTypeName, productSpecDesc string,
	createTime time.Time, orderType, orderStatus int32, isUTC bool) error {
	order := CreateOnDemandOrder(userId, platformType, couponId,
		cloudUserId, cloudResourceId, cloudResourceName, regionCode,
		availabilityZoneCode, serviceTypeCode, serviceTypeName, productSpecDesc,
		createTime, orderType, orderStatus, isUTC)
	err := dao.GetOnDemandOrderao().SaveOnDemandOrderInfo([]*model.OnDemandOrder{order})
	if err != nil {
		logger.Error("save on demand order error: %v, orderId: %s", err.Error(), order.OrderId)
		return errors.New("增加按需订单失败")
	}
	return nil
}

// 创建云上按需资源订单
// 1.从按需资源得到--按需资源列表上所有的资源(无论资源状态)都是新增的订单
// 2.但是只有正常开通的资源才会在实际的用户资源列表中

func CreateAndSaveCloudOnDemandOrder(userId, couponId string,
	cloudResources *bssModel.ListCustomerOnDemandResourcesResponse) (*time.Time, error) {
	if cloudResources == nil {
		return nil, nil
	}
	if *cloudResources.TotalCount == 0 {
		return nil, nil
	}

	//记录最新更新时间
	updateTime := util.GetDefaultTime()

	//以年份为跨度
	createdTime := util.GetUTC(time.Now())
	orders := [3][]*model.OnDemandOrder{}
	//按年份划分orders,createdTime-1,createdTime,createdTime+1年，总共3年
	createdYearNow := createdTime.Year()
	createdYearBefore := createdYearNow - 1

	platformType := platformTypeOfCloud
	orderStatus := orderStatusOfCompleted
	orderType := onDemandOrderTypeOfPurchase
	for _, cloudResource := range *cloudResources.Resources {
		order := CreateOnDemandOrderWithCloudResource(userId, platformType, couponId, orderType, orderStatus, cloudResource)
		if order == nil {
			continue
		}
		orderTime := order.CreatedTime.Year() - createdYearBefore
		orders[orderTime] = append(orders[orderTime], order)
		if order.CreatedTime.After(updateTime) {
			updateTime = order.CreatedTime
		}
	}
	//批量插入order--，处理orderMap
	for _, orderData := range orders {
		err := dao.GetOnDemandOrderao().SaveOnDemandOrderInfo(orderData)
		if err != nil {
			logger.Error(err.Error())
			return nil, errors.New("更新订单失败")
		}
	}
	return &updateTime, nil
}

// 拉取云上按需资源列表
func PullCloudOnDemandResource(cloudUserId string,
	regionCode, serviceTypeCode, effectiveTimeBegin,
	effectiveTimeEnd, indirectPartnerId *string,
	resourceIds *[]string, offset, limit, resourceStatus *int32) (*bssModel.ListCustomerOnDemandResourcesResponse, error) {
	response, err := toolcbc.GetCloudOnDemandResources(
		cloudUserId, regionCode, serviceTypeCode, effectiveTimeBegin,
		effectiveTimeEnd, indirectPartnerId, resourceIds, offset, limit, resourceStatus)
	if err != nil {
		logger.Error("get cloud on demand resource error: %v, cloudUserId: %s", err.Error(), cloudUserId)
		return nil, errors.New("拉取按需资源失败")
	}
	return response, nil
}

func PullAndSaveCloudOnDemandResourceAll(
	userId, cloudUserId, couponId string,
	regionCode, serviceTypeCode, effectiveTimeBegin,
	effectiveTimeEnd, indirectPartnerId *string,
	resourceIds *[]string, offset, limit, resourceStatus *int32) (*time.Time, error) {
	var updateTime *time.Time = nil
	for {
		response, err := PullCloudOnDemandResource(
			cloudUserId, regionCode, serviceTypeCode, effectiveTimeBegin,
			effectiveTimeEnd, indirectPartnerId, resourceIds,
			offset, limit, resourceStatus)
		if err != nil {
			logger.Error(err.Error())
			return nil, err
		}
		if *response.TotalCount == 0 {
			break
		}
		//创建按需订单
		lastTime, err := CreateAndSaveCloudOnDemandOrder(userId, couponId, response)
		if err != nil {
			logger.Error("create on demand order error: %v, userId: %s", err.Error(), userId)
			return nil, err
		}
		if updateTime == nil {
			updateTime = lastTime
		} else {
			if lastTime != nil {
				if (*lastTime).After(*updateTime) {
					updateTime = lastTime
				}
			}
		}
		if (*limit + *offset) > *response.TotalCount {
			break
		}
		*offset = (*offset + *limit)
	}
	return updateTime, nil
}

func PullAndSaveOnDemandResouceLastestOne(userId, couponId, cloudUserId string) error {
	limit := defaultLimit
	offset := defaultOffset
	resourceStatus := resourceStatusOfNormal
	//获取更新时间
	orderRecord, err := GetOrderUpdateRecordOneWithUserId(userId)
	if err != nil {
		return err
	}
	if orderRecord == nil {
		logger.Warn("Can't find the on demand order update time of record.")
		return nil
	}
	efftiveTimeBeg := util.GetTimeString(orderRecord.OnDemandResourceUpdateTime)
	updateTime, err := PullAndSaveCloudOnDemandResourceAll(userId, cloudUserId, couponId,
		nil, nil, &efftiveTimeBeg, nil, nil, nil, &offset, &limit, &resourceStatus)
	if err != nil {
		return err
	}
	//更新拉取时间(UTC)
	var updateTimeSec *int64
	if updateTime != nil {
		lastTime := (*updateTime).Add(1 * time.Second)
		timeSec := util.GetMilliSec(lastTime)
		updateTimeSec = &timeSec
	}
	err = UpdateOrderRecord(userId, nil, updateTimeSec)
	if err != nil {
		return err
	}
	//只会获取当前用户持有的按需资源，全部加入按需资源列表
	return nil
}

// 对所有用户拉取按需资源
func PullAndSaveOnDemandResouceLastestAll(userId, couponId, cloudUserId []string) error {
	if len(userId) == 0 || len(cloudUserId) == 0 {
		return nil
	}
	useCouponId := false
	if len(couponId) == len(userId) && len(userId) > 0 {
		useCouponId = true
	}
	for index, _ := range userId {
		nowUser := userId[index]
		nowCouponId := ""
		if useCouponId {
			nowCouponId = couponId[index]
		}
		nowCloudUser := cloudUserId[index]
		err := PullAndSaveOnDemandResouceLastestOne(nowUser, nowCouponId, nowCloudUser)
		if err != nil {
			logger.Error(err.Error())
			return err
		}
	}
	return nil
}

// 查询按需订单信息
func buildQueryParameterForGetOnDemandOrder(userId, cloudUserId, orderId, platformType, resourceId []string,
	orderType []int32, createdTimeBegin, createdTimeEnd *int64, page, pageSize *int, timeReverseOrder *bool) *common.QueryOnDemandOrderDetail {
	queryParameter := &common.QueryOnDemandOrderDetail{
		UserId:           userId,
		CloudUserId:      cloudUserId,
		OrderId:          orderId,
		PlatformType:     platformType,
		OrderType:        orderType,
		ResourceId:       resourceId,
		CreatedTimeBegin: createdTimeBegin,
		CreatedTimeEnd:   createdTimeEnd,
		Page:             page,
		PageSize:         pageSize,
		TimeReverseOrder: timeReverseOrder,
	}
	return queryParameter
}
func GetOnDemandOrderWithParameter(queryParameter *common.QueryOnDemandOrderDetail) ([]*model.OnDemandOrder, int, error) {
	if queryParameter == nil {
		return nil, 0, nil
	}
	onDemandOrder, totalCount, err := dao.GetOnDemandOrderao().GetOnDemandOrderInfo(queryParameter)
	if err != nil {
		logger.Error(err.Error())
		return nil, 0, errors.New("查询按需订单失败")
	}
	return onDemandOrder, totalCount, nil
}

func GetOnDemandOrderAll(userId, cloudUserId, orderId, platformType, resourceId []string,
	orderType []int32, createdTimeBegin, createdTimeEnd *int64, page, pageSize *int, timeReverseOrder *bool) ([]*model.OnDemandOrder, int, error) {
	return GetOnDemandOrderWithParameter(buildQueryParameterForGetOnDemandOrder(userId, cloudUserId, orderId, platformType,
		resourceId, orderType, createdTimeBegin, createdTimeEnd, page, pageSize, timeReverseOrder))
}
func GetOnDemandOrderWithPlatformAndResourceId(platformType, resourceId string) (*model.OnDemandOrder, error) {
	queryParameter := &common.QueryOnDemandOrderDetail{
		PlatformType: []string{platformType},
		ResourceId:   []string{resourceId},
	}
	onDemandOrder, totalCount, err := GetOnDemandOrderWithParameter(queryParameter)
	if err != nil {
		logger.Error("get on demand order error: %v, platformType %s, resourceId: %s", err.Error(), platformType, resourceId)
		return nil, err
	}
	if totalCount == 0 {
		return nil, nil
	}
	return onDemandOrder[0], nil
}
func GetOnDemandOrderWithResourceId(resourceId string) (*model.OnDemandOrder, error) {
	queryParameter := &common.QueryOnDemandOrderDetail{
		ResourceId: []string{resourceId},
	}
	onDemandOrder, totalCount, err := GetOnDemandOrderWithParameter(queryParameter)
	if err != nil {
		logger.Error("get on demand error: %v, resourceId: %s", err.Error(), resourceId)
		return nil, err
	}
	if totalCount == 0 {
		return nil, nil
	}
	return onDemandOrder[0], nil
}

// 构建返回体--包周期订单查询
func buildQueryParameterFromOnePayOrderRequest(req *common.OrderOnePayQueryRequest) *common.QueryOnePayOrderDetail {
	if req == nil {
		return nil
	}
	nowTime := time.Now()
	var createdTime *time.Time = nil
	var createdSec *int64 = nil
	if req.TimeRange != nil {
		if *req.TimeRange == util.InLastMonth {
			t := nowTime.AddDate(0, -1, 0)
			createdTime = &t
		} else if *req.TimeRange == util.InLastThreeMonths {
			t := nowTime.AddDate(0, -3, 0)
			createdTime = &t
		} else if *req.TimeRange == util.InLastSixMonths {
			t := nowTime.AddDate(0, -6, 0)
			createdTime = &t
		} else if *req.TimeRange == util.InLastYear {
			t := nowTime.AddDate(-1, 0, 0)
			createdTime = &t
		} else if *req.TimeRange == util.InAllTime {
			createdTime = nil
		}
	} else {
		//缺省默认为最近一个月
		t := nowTime.AddDate(0, -1, 0)
		createdTime = &t
	}
	if createdTime != nil {
		creatTimeData := util.GetMilliSec(*createdTime)
		createdSec = &creatTimeData
	}
	orderId := []string{}
	if req.OrderId != nil {
		orderId = append(orderId, *req.OrderId)
	}
	queryParameter := BuildQueryParameterForGetOnePayOrder([]string{req.UserId},
		nil, orderId, nil, nil, req.OrderType, req.OrderStatus,
		createdSec, nil, nil, nil, nil, req.Page, req.PageSize, req.TimeReverseOrder)
	return queryParameter
}
func BuildResponseForQueryOnePayOrder(req *common.OrderOnePayQueryRequest) (*common.OrderOnePayQueryResponse, error) {
	if req == nil {
		return nil, nil
	}
	queryParameter := buildQueryParameterFromOnePayOrderRequest(req)
	if queryParameter == nil {
		return nil, nil
	}
	onePayOrders, totalCount, err := GetOnePayOrderAllWithParamenter(queryParameter)
	if err != nil {
		logger.Error(err.Error())
		return nil, err
	}
	response := &common.OrderOnePayQueryResponse{
		Size:       len(onePayOrders),
		TotalCount: totalCount,
	}
	orders := []common.OnePayOrderInfo{}
	for _, order := range onePayOrders {
		addOrder := common.OnePayOrderInfo{
			UserId:             order.UserId,
			OrderId:            order.OrderId,
			OrderStatus:        order.OrderStatus,
			OrderType:          order.OrderType,
			CreatedTime:        util.GetTimeString(order.CreatedTime),
			PaymentTime:        util.GetTimeString(order.PaymentTime),
			Price:              order.PaymentAmount,
			ServiceTypeName:    order.ServiceTypeName,
			ProductionSpecDesc: order.ProductionSpecDesc,
			OrderExpiredTime:   util.GetTimeString(order.OrderExpiredTime),
		}
		if !util.IsDefaultTime(order.ResourceExpiredTime) {
			addOrder.ResourceExpiredTime = util.GetTimeString(order.ResourceExpiredTime)
		}
		orders = append(orders, addOrder)
	}
	response.Order = orders
	return response, nil
}

// 构建返回体--按需订单查询
func buildQueryParameterForQueryOnDemandOrder(req *common.OrderOnDemandQueryRequest) (*common.QueryOnDemandOrderDetail, error) {
	if req == nil {
		return nil, nil
	}
	if req.CreatedTimeBegin != nil && req.CreatedTimeEnd != nil {
		timeBegin := util.GetUTCFromMilliSec(req.CreatedTimeBegin)
		timeEnd := util.GetUTCFromMilliSec(req.CreatedTimeEnd)
		diff := timeEnd.Sub(*timeBegin)
		days := diff.Hours() / util.OneDayHours
		if days > util.QueryOnDemandOrderLimitedDays {
			return nil, errors.New("查询时间间隔不能超过31天")
		}
	} else {
		timeEnd := time.Now()
		timeBeg := timeEnd.AddDate(0, -1, 0)
		begSec := util.GetMilliSec(timeBeg)
		endSec := util.GetMilliSec(timeEnd)
		req.CreatedTimeBegin = &begSec
		req.CreatedTimeBegin = &endSec
	}
	orderId := []string{}
	if req.OrderId != nil {
		orderId = append(orderId, *req.OrderId)
	}
	queryParameter := buildQueryParameterForGetOnDemandOrder([]string{req.UserId},
		nil, orderId, nil, nil, req.OrderType, req.CreatedTimeBegin, req.CreatedTimeEnd, req.Page, req.PageSize, req.TimeReverseOrder)
	return queryParameter, nil
}

func BuildResponseForQueryOnDemandOrder(req *common.OrderOnDemandQueryRequest) (*common.OrderOnDemandQueryResponse, error) {
	if req == nil {
		return nil, nil
	}
	queryParameter, err := buildQueryParameterForQueryOnDemandOrder(req)
	if err != nil {
		logger.Error(err.Error())
		return nil, err
	}
	onDemandOrder, totalCount, err := GetOnDemandOrderWithParameter(queryParameter)
	if err != nil {
		return nil, err
	}
	response := &common.OrderOnDemandQueryResponse{
		Size:       len(onDemandOrder),
		TotalCount: totalCount,
	}
	orders := []common.OnDemandOrderInfo{}
	for _, order := range onDemandOrder {
		addOrder := common.OnDemandOrderInfo{
			UserId:               order.UserId,
			OrderId:              order.OrderId,
			OrderStatus:          order.OrderStatus,
			OrderType:            order.OrderType,
			CreatedTime:          util.GetTimeString(order.CreatedTime),
			ServiceTypeName:      order.ServiceTypeName,
			RegionCode:           order.RegionCode,
			AvailabilityZoneCode: order.AvailabilityZoneCode,
			ProductSpecDesc:      order.ProductSpecDesc,
		}
		orders = append(orders, addOrder)
	}
	response.Order = orders
	return response, nil
}

// 更新订单--可更新订单状态和使用优惠券
func UpdateOnePayOrder(orderId string, orderStatus *int32, couponId *string) error {
	order, err := GetOnePayOrderWithOrderId(orderId)
	if err != nil {
		logger.Error("update one pay order error: %v, orderId %s", err.Error(), orderId)
		return err
	}
	if orderStatus != nil {
		if ValidateOrderStatus(*orderStatus) {
			order.OrderStatus = *orderStatus
		}
	}
	if couponId != nil {
		// //校验优惠券有效性--TODO--ValidateCoupon(couponId)
		order.CouponId = *couponId
	}
	err = dao.GetOnePayOrderDao().UpdateOnePayOrderInfo(order)
	if err != nil {
		logger.Error("update one pay order error: %v, orderId %s", err.Error(), orderId)
		return err
	}
	return nil
}

// 支付包周期订单，不依赖账单服务
// 1.对于云上订单，此处直接支付，账单在云上产生，此处只修改订单状态
// 2.对于自有订单，此处直接支付，由调用方产生订单，此处只修改订单状态
// 3.对于云上订单产生的账单，由账单拉取服务生成系统账单
// 4.对于自有订单，由账单服务扫描订单表生成系统账单
// 5.扣费只依赖于账单服务
func PayCustomerOnePayOrder(order *model.OnePayOrder) error {
	if order == nil {
		return errors.New("订单不存在")
	}
	if !IsOrderStatusOfToBePaid(order.OrderStatus) {
		return errors.New("仅可支付处于“待支付”状态的订单")
	}
	if IsCloudPlatform(order.PlatformType) {
		cloudCoupons := []bssModel.CouponSimpleInfoOrderPayV3{}
		cloudDiscount := []bssModel.DiscountSimpleInfoV3{}
		//支付云上订单
		_, err := toolcbc.PayCloudOnePayOrder(order.CloudUserId, order.CloudOrderId, cloudCoupons, cloudDiscount)
		if err != nil {
			logger.Error("pay cloud one pay order error: %v, orderId %s", err.Error(), order.OrderId)
			return err
		}
		//重新拉取订单详情，写入失效时间
		detail, err := PullCloudOnePayOrderDetail(order.CloudOrderId, nil, nil, nil)
		if err != nil {
			logger.Error("pay cloud one pay order error: %v, orderId %s", err.Error(), order.OrderId)
			return err
		}
		if detail != nil && *detail.TotalCount > 0 {
			for _, info := range *detail.OrderLineItems {
				if info.ExpireTime != nil {
					resourceExpiredTime, err := util.GetTimeFromUTCStr(*info.ExpireTime)
					if err != nil {
						logger.Error(err.Error())
						continue
					}
					order.ResourceExpiredTime = resourceExpiredTime
				}
			}
		}
		//支付订单--修改数据库
		orderStatus := orderStatusOfCompleted
		err = UpdateOnePayOrder(order.OrderId, &orderStatus, nil)
		if err != nil {
			logger.Error("update one pay order error: %v, orderId %s", err.Error(), order.OrderId)
			return err
		}
	} else if IsSelfPlatform(order.PlatformType) {
		//支付订单--修改数据库
		orderStatus := orderStatusOfCompleted
		err := UpdateOnePayOrder(order.OrderId, &orderStatus, nil)
		if err != nil {
			logger.Error("update one pay order error: %v, orderId %s", err.Error(), order.OrderId)
			return err
		}
	} else {
		return errors.New("错误的订单类型")
	}
	return nil
}

// 取消订单
func CancelCustomerOnePayOrder(order *model.OnePayOrder) error {
	if order == nil {
		return errors.New("订单不存在")
	}
	if !IsOrderStatusOfToBePaid(order.OrderStatus) {
		return errors.New("仅可取消处于“待支付”状态的订单")
	}
	if IsCloudPlatform(order.PlatformType) {
		_, err := toolcbc.CancelCloudOnePayOrder(order.CloudUserId, order.CloudOrderId)
		if err != nil {
			logger.Error("cancel cloud one Pay order error: %v, orderId %s", err.Error(), order.OrderId)
			return err
		}
		//取消订单--修改数据库
		orderStatus := orderStatusOfCancelled
		err = UpdateOnePayOrder(order.OrderId, &orderStatus, nil)
		if err != nil {
			logger.Error("update one pay order error: %v, orderId %s", err.Error(), order.OrderId)
			return err
		}
	} else if IsSelfPlatform(order.PlatformType) {
		// 取消自有平台包周期订单
		orderStatus := orderStatusOfCancelled
		err := UpdateOnePayOrder(order.OrderId, &orderStatus, nil)
		if err != nil {
			logger.Error("update one pay order error: %v, orderId %s", err.Error(), order.OrderId)
			return err
		}
	} else {
		return errors.New("错误的订单类型")
	}
	return nil
}
